package cn.cellcom.agent.my.tag;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.cellcom.jar.util.ABean;
import cn.cellcom.jar.util.AU;
import cn.cellcom.jar.util.BeanUtil;
import cn.cellcom.jar.util.CU;
import cn.cellcom.jar.util.Equals;
import cn.cellcom.jar.util.form.FormUtil.Input;

public class MySelect extends TagSupport {

	private Log log = LogFactory.getLog(this.getClass());

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private static final String SPLIT_CHAR = ";";

	@Override
	public int doStartTag() throws JspException {
		init();

		JspWriter out = pageContext.getOut();
		try {
			List<ABean> list = (List<ABean>) pageContext.getRequest().getAttribute(this.list);
			if (AU.isBlank(list))
				list = (List<ABean>) pageContext.getServletContext().getAttribute(this.list);
			// 如果找不到数据列表，但存在数据列表名，明确名称中包含有$，则进行分割作为数据返回，支持直接在jsp中给出数据
			if (AU.isBlank(list) && StringUtils.isNotBlank(this.list) && this.list.contains(SPLIT_CHAR)) {
				list = new ArrayList<ABean>();
				List<String> tmp = AU.toList(CU.splitString(this.list, SPLIT_CHAR, false));
				for (int i = 0; tmp != null && i < tmp.size(); i++) {
					String one = tmp.get(i);
					ABean e = null;
					if (one.indexOf(":") > 0) {
						String[] arr = one.split(":");
						e = new ABean(arr[0], arr[0], arr[1], null);
					} else {
						e = new ABean(String.valueOf(i), tmp.get(i), tmp.get(i), null);
					}
					list.add(e);
				}
			}
			List<ABean> list2 = deleteFitler(list);
			List<ABean> list3 = compareValue(list2);
			List<ABean> list4 = prependAndAppend(list3);
			if (list4.size() == 0) {
				out.write("无相关数据");
			} else if (this.showonly) {
				out.write(showonly(list4));
			} else if ("radio".equals(this.getType())) {
				out.write(radio(list4));
			} else if ("checkbox".equals(this.getType())) {
				out.write(checkbox(list4));
			} else {
				out.write(select(list4));
			}
		} catch (Exception e) {
			log.error("操作出现错误", e);
		}
		return 0;
	}

	/**
	 * 插入和补充数据
	 * 
	 * @param list
	 * @return
	 */
	private List<ABean> prependAndAppend(List<ABean> list) {
		if (StringUtils.isNotBlank(this.prepend)) {
			String[] arr = this.prepend.split(SPLIT_CHAR);
			for (int i = 0; i < arr.length; i++) {
				String[] arr2 = arr[i].split(":");
				ABean e = new ABean("key-1", CU.trimAll(arr2[0]), CU.trimAll(arr2[1]), null);
				list.add(0, e);
			}
		}
		if (StringUtils.isNotBlank(this.append)) {
			String[] arr = this.append.split(SPLIT_CHAR);
			for (int i = 0; i < arr.length; i++) {
				String[] arr2 = arr[i].split(":");
				ABean e = new ABean("key-1", CU.trimAll(arr2[0]), CU.trimAll(arr2[1]), null);
				list.add(0, e);
			}
		}
		return list;
	}

	/**
	 * 按照比较进行过滤
	 * 
	 * @param list2
	 * @return
	 */
	private List<ABean> compareValue(List<ABean> list) {
		List<ABean> list3 = null;
		if (StringUtils.isNotBlank(this.compare)) {
			String[] arr = this.compare.split(";");
			for (int a = 0; a < arr.length; a++) {
				list3 = new ArrayList<ABean>();
				double compareValue = 0;
				double compareType = 0;
				if (arr[a].startsWith(">=")) {
					compareValue = Double.parseDouble(arr[a].substring(2));
					compareType = 2;
				} else if (arr[a].startsWith("<=")) {
					compareValue = Double.parseDouble(arr[a].substring(2));
					compareType = 4;
				} else if (arr[a].startsWith(">")) {
					compareValue = Double.parseDouble(arr[a].substring(1));
					compareType = 1;
				} else if (arr[a].startsWith("<")) {
					compareValue = Double.parseDouble(arr[a].substring(1));
					compareType = 3;
				}

				// 去除过滤的
				for (int i = 0; list != null && i < list.size(); i++) {
					ABean abean = list.get(i);
					Double vl = Double.parseDouble(abean.getValue());
					if (compareType == 3) {// 配置了：显示的值必须小于指定值
						if (vl < compareValue) {
							list3.add(abean);
						}
					} else if (compareType == 4) {
						if (vl <= compareValue) {
							list3.add(abean);
						}
					} else if (compareType == 1) {
						if (vl > compareValue) {
							list3.add(abean);
						}
					} else if (compareType == 2) {
						if (vl >= compareValue) {
							list3.add(abean);
						}
					}
				}
				list = list3;
			}
		} else {
			list3 = list;
		}
		return list3;
	}

	/**
	 * 删除被过滤的值
	 * 
	 * @param list
	 * @return
	 */
	private List<ABean> deleteFitler(List<ABean> list) {
		List<ABean> list2 = new ArrayList<ABean>();
		if (StringUtils.isBlank(filterField)) {
			list2 = list;
		} else {
			Equals eql = new Equals() {
				@Override
				public boolean equals(Object o1, Object o2) {
					return String.valueOf(o1).equals(String.valueOf(o2));
				}
			};

			String[] filters = CU.splitString(this.filter, SPLIT_CHAR, false);
			// 去除过滤的
			for (int i = 0; list != null && i < list.size(); i++) {
				ABean o = list.get(i);
				if ("value".equals(filterField) && CU.isExist(filters, o.getValue(), eql) < 0) {
					list2.add(o);
				}
				if ("object".equals(filterField) && CU.isExist(filters, o.getObject(), eql) < 0) {
					list2.add(o);
				}
				if ("object2".equals(filterField) && CU.isExist(filters, o.getObject2(), eql) < 0) {
					list2.add(o);
				}
			}
		}
		return list2;
	}

	private void init() {
		if (id == null) {
			id = name;
		}
		if (StringUtils.isBlank(value)) {
			HttpSession session = (HttpSession) pageContext.getSession();
			List<Input> inputs = (List<Input>) session.getAttribute("PG-" + pageContext.getRequest().getParameter("entityName"));
			if (inputs != null) {
				for (int i = 0; i < inputs.size(); i++) {
					Input input = inputs.get(i);
					if (input.getName().equals(this.name)) {
						this.value = String.valueOf(input.getValue());
						break;
					}
				}
			}
		}
		if (StringUtils.isBlank(value)) {
			value = default2;
		}
	}

	/**
	 * 仅显示文字
	 * 
	 * @param list
	 * @return
	 */
	public String showonly(List<ABean> list) {
		StringBuffer sb = new StringBuffer();
		// 如果只是可读，就直接将object内容返回
		if (showonly) {
			String[] vls = value.split(SPLIT_CHAR);
			for (int l = 0; l < vls.length; l++) {
				String vl = vls[l];
				for (int i = 0; list != null && i < list.size(); i++) {
					ABean abean = list.get(i);
					if (StringUtils.equals(vl, abean.getValue())) {
						if (sb.length() > 0)
							sb.append(SPLIT_CHAR);
						sb.append(abean.getObject());
					}
				}
			}
			// 如果list中没有value所对应的内容，就使用other所给出的值来找到list中对应的
			if (sb.length() == 0 && StringUtils.isNotBlank(this.getFill())) {
				Object fillObject = BeanUtil.getObjectFromValue(this.getFill(), list);
				if (fillObject == null) {
					sb.append(this.getFill());
				} else {
					sb.append(String.valueOf(fillObject));
				}

			}
			// 没有相应值的时候
			if (sb.length() == 0) {
				sb.append(value);
			}
			// 指定了显示的文字长度
			if (max > 0) {
				sb = new StringBuffer(CU.subString(sb.toString(), max, StringUtils.isNotBlank("……")));
			}
			if (width > 0)
				sb.insert(0, "<div style='width:" + width + "px'>").append("</div>");
			return sb.toString();
		}
		return sb.toString();
	}

	/**
	 * 多选框
	 * 
	 * @param list
	 * @return
	 */
	private String checkbox(List<ABean> list) {
		StringBuffer result = new StringBuffer();
		for (int i = 0; i < list.size(); i++) {
			ABean abean = list.get(i);
			String readonly = this.readonly ? " readonly='readonly'" : "";
			String checked = StringUtils.equals(value, abean.getValue())
					|| (value != null && CU.isExist(value.split(SPLIT_CHAR), abean.getValue(), null) >= 0) ? " checked" : "";

			result.append("<input type='checkbox' name='").append(name).append("' value='").append(abean.getValue()).append("' ").append(readonly)
					.append(checked);
			result.append(" ").append(added);
			result.append("/>" + abean.getObject());
		}
		return result.toString();
	}

	/**
	 * 单选
	 * 
	 * @param list
	 * @return
	 */
	private String radio(List<ABean> list) {
		StringBuffer result = new StringBuffer();
		for (int i = 0; i < list.size(); i++) {
			ABean abean = list.get(i);
			String checked = abean.getValue().equals(value) ? " checked" : "";
			String readonly = this.readonly ? " readonly='readonly'" : "";
			result.append("<input type='radio' name='").append(name).append("' value='").append(abean.getValue()).append("' ").append(readonly)
					.append(checked);
			added = CU.replace(added, "\\\"", "\"");
			result.append(" ").append(added);
			result.append("/>" + abean.getObject());
		}
		return result.toString();
	}

	/**
	 * 下拉列表
	 * 
	 * @param list
	 * @return
	 */
	public String select(List<ABean> list) {
		StringBuffer sb = new StringBuffer();
		// 可选择，就是作为一个select返回
		sb.append("<select name='").append(name).append("' id='").append(id).append("'");
		if (width > 0 && height > 0) {
			sb.append(" style='width:").append(width).append("px;height:").append(height).append("px'");
		}
		if (size > 1) {
			sb.append("  multiple='multiple' size='" + size + "'");
		}
		if (StringUtils.isNotBlank(css)) {
			sb.append("  class='" + css + "'");
		}
		added = CU.replace(added, "\\\"", "\"");
		sb.append(" ").append(added).append(">");

		for (int i = 0; list != null && i < list.size(); i++) {
			ABean abean = list.get(i);
			boolean checked = StringUtils.equals(value, abean.getValue())
					|| (value != null && CU.isExist(value.split(SPLIT_CHAR), abean.getValue(), null) >= 0);
			String selected = checked ? "selected='true'" : "";
			// 等于只读的value,或者非只读
			if (!readonly || (readonly && abean.getValue().equals(value))) {
				sb.append("	  <option value='").append(abean.getValue()).append("' ").append(selected).append(">").append(abean.getObject()).append("</option>");
			}
		}
		sb.append("</select>");

		return sb.toString();
	}

	private boolean showonly;// 只显示，就没有选择框

	private boolean readonly;// 只读，那么选择框中只有该选项

	private int max;

	private String prepend;// 在最前面插入

	private String append;// 在最后面插入

	private String fill;// 如果list中没有给定value值所对应的内容时，就显示fill值在list中所对应的内容

	private String name;

	private String id;

	private String list;

	private String added = "";// 添加的特殊字符串，如css等

	private int size = 1;

	private String type = "select";

	private String default2;

	private String value;// 指定值显示，可支持多个用;分隔

	private String filter;// 过滤掉某些选项，多个过滤值可以用分号分开

	private String filterField = "value";// 被过滤的字段，只可以选择：value、object、object2，默认是value

	private String compare;// value比较

	private String css;//指定样式

	private int width;//指定宽度

	private int height = 30;//指定高度

	public String getCss() {
		return css;
	}

	public void setCss(String css) {
		this.css = css;
	}

	public int getMax() {
		return max;
	}

	public void setMax(int max) {
		this.max = max;
	}

	public String getDefault2() {
		return default2;
	}

	public void setDefault2(String default2) {
		this.default2 = default2;
	}

	public boolean isShowonly() {
		return showonly;
	}

	public void setShowonly(boolean showonly) {
		this.showonly = showonly;
	}

	public boolean isReadonly() {
		return readonly;
	}

	public void setReadonly(boolean readonly) {
		this.readonly = readonly;
	}

	public String getPrepend() {
		return prepend;
	}

	public void setPrepend(String prepend) {
		this.prepend = prepend;
	}

	public String getAppend() {
		return append;
	}

	public void setAppend(String append) {
		this.append = append;
	}

	public String getFill() {
		return fill;
	}

	public void setFill(String fill) {
		this.fill = fill;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public String getList() {
		return list;
	}

	public void setList(String list) {
		this.list = list;
	}

	public String getAdded() {
		return added;
	}

	public void setAdded(String added) {
		this.added = added;
	}

	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getFilter() {
		return filter;
	}

	public void setFilter(String filter) {
		this.filter = filter;
	}

	public String getFilterField() {
		return filterField;
	}

	public void setFilterField(String filterField) {
		this.filterField = filterField;
	}

	public String getCompare() {
		return compare;
	}

	public void setCompare(String compare) {
		this.compare = compare;
	}

}
